use std::{fmt, num::ParseIntError, str::ParseBoolError};
use log::SetLoggerError;

pub type ConfigResult<T> = Result<T,ConfigError>; 

#[derive(Debug)]
pub enum ConfigError {
    InvalidGetVar(String),
    InvalidSetVar(String),
    SfNumOverFlow,
    NoneSmoothSfNumOverFlow,
    IntTypeMismatch(String,ParseIntError),
    BoolTypeMismatch(String,ParseBoolError),
    BackupPathMissing,
    RestorePathMissing,
    WoringDirMissing,
    LoggerSetNone,
    UnknownChunkingAlgorithm(String),
    UnknownSuperfeatureAlgorithm(String),
    LogInit(SetLoggerError),
    Other(String),
}

impl fmt::Display for ConfigError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            ConfigError::InvalidGetVar(var) => write!(f,"Error invalid get var {}",var),
            ConfigError::InvalidSetVar(var) => write!(f,"Error invalid set var {}",var),
            ConfigError::SfNumOverFlow => write!(f,"Error sf num overflow"),
            ConfigError::NoneSmoothSfNumOverFlow => write!(f,"Error sf num of none smooth can only be three"),
            ConfigError::IntTypeMismatch(var, e) => write!(f,"Error {} is integer,its value parse error {} ",var,e),
            ConfigError::BoolTypeMismatch(var, e) => write!(f,"Error {} is bool,its value parse error {} ",var,e),
            ConfigError::BackupPathMissing => write!(f,"Error backup path argument missing"),
            ConfigError::RestorePathMissing => write!(f,"Error restore path argument missing"),
            ConfigError::WoringDirMissing => write!(f,"Error working directory missing"),
            ConfigError::LoggerSetNone => write!(f,"Error logger is initialized,so it can't be set to none"),
            ConfigError::UnknownChunkingAlgorithm(algorithm) => write!(f,"Error unkown chunking algorithm {}",algorithm),
            ConfigError::UnknownSuperfeatureAlgorithm(algorithm) => write!(f,"Error unkown superfeature algorithm {}",algorithm),
            ConfigError::LogInit(e) => write!(f,"Error log init:{}",e),
            ConfigError::Other(info) => write!(f,"Error {}",info),
        }
    }
}

impl std::error::Error for ConfigError {}

impl From<SetLoggerError> for ConfigError {
    fn from(value: SetLoggerError) -> Self {
        Self::LogInit(value)
    }
}
